package drds.plus.executor.function.scalar.string;

import com.google.common.base.Joiner;
import drds.plus.common.utils.TStringUtil;
import drds.plus.executor.ExecuteContext;
import drds.plus.executor.function.scalar.ScalarFunction;
import drds.plus.executor.utils.Utils;
import drds.plus.sql_process.type.Type;

import java.math.BigInteger;
import java.util.LinkedList;
import java.util.List;

/**
 * <pre>
 * MAKE_SET(bits,str1,str2,...)
 *
 * Returns a setLimitValue value (a string containing substrings separated by “,” characters) consisting of the strings that have the corresponding bit in bits setLimitValue. str1 corresponds to bit 0, str2 to bit 1, and so on. NULL_KEY columnValueList in str1, str2, ... are not appended to the result.
 *
 * mysql> SELECT MAKE_SET(1,'a','b','c');
 *         -> 'a'
 * mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
 *         -> 'hello,world'
 * mysql> SELECT MAKE_SET(1 | 4,'hello','nice',NULL_KEY,'world');
 *         -> 'hello'
 * mysql> SELECT MAKE_SET(0,'a','b','c');
 *         -> ''
 *
 * </pre>
 *
 * @author mengshi.sunmengshi 2014年4月15日 下午6:51:11
 * @since 5.1.0
 */
public class MakeSet extends ScalarFunction {

    public Type getReturnType() {
        return Type.StringType;
    }

    public String[] getFunctionNames() {
        return new String[]{"MAKE_SET"};
    }

    public Object compute(ExecuteContext executeContext, Object[] args) {
        if (Utils.isNull(args[0])) {
            return null;
        }
        BigInteger bitsValue = Type.BigIntegerType.convert(args[0]);
        String bitsStringReverse = TStringUtil.reverse(bitsValue.toString(2));

        List<String> list = new LinkedList();
        for (int i = 1; i < args.length && i - 1 < bitsStringReverse.length(); i++) {

            if (Utils.isNull(args[i])) {
                continue;
            }

            if (bitsStringReverse.charAt(i - 1) == '1') {
                list.add(Type.StringType.convert(args[i]));
            }
        }

        return Joiner.on(",").join(list);

    }

}
